package elec315.chatroom.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import elec315.chatroom.core.dispatcher.MessageDispatcher;
import elec315.chatroom.core.dispatcher.ServerMessageDispatcher;
import elec315.chatroom.core.processor.ServerMessageProcessor;
import elec315.chatroom.net.ServerSocketHandler;

public class ChatServer implements Runnable {

	private static final Log logger = LogFactory.getLog(ChatServer.class);

	private final int port;

	public ChatServer(int port) throws IOException {
		this.port = port;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		ServerSocket serverSocket = null;
		try {
			serverSocket = new ServerSocket(port);
			logger.info(">>>======================================================================================");
			logger.info("Server is started at " + new Date());
			logger.info("Press \"Ctrl + C\" to exit.");
			logger.info("<<<======================================================================================");
			List<String> userIds = new ArrayList<String>();
			while (true) {
				try {
					Socket socket = serverSocket.accept();
					if (socket != null) {
						logger.info("Client is connected from " + socket.getInetAddress());
						MessageDispatcher messageDispatcher = new ServerMessageDispatcher(new ServerMessageProcessor(userIds));
						ServerSocketHandler handler = new ServerSocketHandler(socket, messageDispatcher);
						handler.start();
					}
				} catch (IOException ex) {
					logger.error(ex, ex);
				}
			}
		} catch (IOException ex) {
			logger.error(ex, ex);
		} finally {
			try {
				serverSocket.close();
				logger.info(">>>======================================================================================");
				logger.info("Server stopped.");
				logger.info("<<<======================================================================================");
			} catch (IOException ex) {
				logger.error(ex, ex);
			}
		}
	}

}
